using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Admin2022Soft1.Infrastructure.Persistence;
using Admin2022Soft1.Application.Common.Interface;
using Admin2022Soft1.Infrastructure.Persistence.Repository;
using Admin2022Soft1.Infrastructure.Identity;
using Admin2022Soft1.Infrastructure.File;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Admin2022Soft1.Application.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Admin2022Soft1.Infrastructure.Utils;
using Microsoft.AspNetCore.Http;

namespace Admin2022Soft1.Infrastructure
{
    public static class DependencyInjection
    {
        public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddDbContext<Admin2022Soft1DbContext>(options =>
                options.UseNpgsql(
                    configuration.GetConnectionString("PostgreSQL"),
                    b => b.MigrationsAssembly(typeof(Admin2022Soft1DbContext).Assembly.FullName)));

            services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
            services.AddTransient<IIdentityService, IdentityService>();
            services.AddScoped<IAppFileUploadService, AppFileUploadService>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(option =>
                {
                    option.RequireHttpsMetadata = false;//配置是否为https协议
                    option.SaveToken = true;//配置token是否保存在api上下文

                    var tokenParameter = configuration.GetSection("JwtSetting").Get<JwtSetting>();
                    option.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,

                        ValidIssuer = tokenParameter.Issuer,
                        ValidAudience = tokenParameter.Audience,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenParameter.Secret))
                    };
                    option.Events = new JwtBearerEvents
                    {
                        //token验证失败后执行
                        OnChallenge = context =>
                        {
                            // 跳过默认响应逻辑
                            context.HandleResponse();
                            // 自定义401时返回的信息
                            var result = JsonHelper.SerializeObject(new { Code = "401", Message = "token验证失败" });
                            context.Response.ContentType = "application/json";
                            //验证失败返回401
                            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                            context.Response.WriteAsync(result);
                            return Task.FromResult(0);
                        }
                    };
                });

            return services;
        }
    }
}